//
// Created by jack on 2021/2/1.
//

#ifndef WEILACSDK_WEILAPB_H
#define WEILACSDK_WEILAPB_H

/**
 * 协议初始化，需要添加几个回调函数，如果没有添加会返回错误。
 * @param pbFunHook
 */
extern PB_BOOL weilapb_init(const PBFunHook* pbFunHook);

/**
 * 设置SDK必要的系统信息，可以在后续登录的时候省掉一些参数设置
 * @param pAppId 所有SDK登录均需要appID，此appID不同开发者不一样，必填
 * @param pAppKey 所有SDK登录均需要appKey，此appKey不同开发者不一样，必填
 * @param pSpecial 设备相关信息,必须按照 {"id":"xxx","imei":"xxx","product":"meizu_M5s"} 此格式的Json字串，必填
 * @param pDevVersion 设备版本信息， 可NULL
 */
extern void weilapb_setDeviceConfig(PB_CHAR* pAppId, PB_CHAR* pAppKey, PB_CHAR* pSpecial, PB_CHAR* pDevVersion);

/**
 * 注册protocol处理网络数据后得到的消息，以事件的方式回调
 * @param pbEventListener 回调函数指针
 */
extern void weilapb_registerListener(PB_EVENT_LISTENER pbEventListener);

/**
 * 把网络收到的数据都喂给此接口，由protocol来缓存和解析结果，并处理后通过回调事件通知调用者
 * @param pData 网络数据
 * @param uDataSize 数据大小
 */
extern void weilapb_feedData(PB_UINT8* pData, PB_INT32 uDataSize);

/**
 * 网络重连调用此接口重置数据缓存区
 */
extern void weilapb_reset_feedData(void);

/**
 * 获取出错的信息。一旦出现错误返回，可以通过此接口获取出错的信息。返回的是PBErrorInfo结构体。
 * @return
 */
extern PBErrorInfo weilapb_getErrorInfo(void);

/**
 * 创建登录请求的编码数据，此数据可以发送到微喇服务器
 * @param pParam 基本的登录参数，此参数有两种，一种是简要的登录参数，如账号和密码，国家区号等，
 *               还有一种是全参数的，对应PBReqLoginExtParam.记住采用不同的参数，对应的sizeOfStruct
 *               必须填上对应的结构体的大小来区分参数的不同。如果额外的参数如appid, appkey等已经在之前
 *               的weilapb_setDeviceConfig设置过，则可以采用基本的登录信息。
 * @return
 */
extern PBEncResult weilapb_buildLoginReq(PBReqLoginParam* pParam);

/**
 * 创建登录请求的编码数据，此数据可以发送到微喇服务器
 * @param pParam 基本的登录参数，此参数有两种，一种是简要的登录参数，如账号和密码，国家区号等，
 *               还有一种是全参数的，对应PBReqLoginExtParam.记住采用不同的参数，对应的sizeOfStruct
 *               必须填上对应的结构体的大小来区分参数的不同。如果额外的参数如appid, appkey等已经在之前
 *               的weilapb_setDeviceConfig设置过，则可以采用基本的登录信息。
 * @param type 登录类型
 * @return
 */
extern PBEncResult weilapb_buildLoginReqWithType(PBReqLoginParam* pParam, int type);

/**
 * 登出服务器
 * @return
 */
extern PBEncResult weilapb_buildLogoutReq(void);

/**
 * 往服务器发送心跳请求
 * @return
 */
extern PBEncResult weilapb_buildHeartbeatReq(void);
extern PBEncResult weilapb_buildHeartbeatWithIntervalReq(PB_UINT32 interval);

/**
 * 服务器如果发送心跳请求到Client，则Client需要发送心跳响应给服务器
 * @return
 */
extern PBEncResult weilapb_buildHeartbeatRsp(void);

/**
 * 刷新access-token
 * @return
 */
extern PBEncResult weilapb_buildRefreshAccessTokenReq(void);

/**
 * 远程关键应答
 * @param guardianId 关机监护人Id
 * @return
 */
extern PBEncResult weilapb_buildAnswerShutdownExtensionReq(PB_UINT32 guardianId);

/**
 * 应答APP端的绑定响应，设备无账号登录会收到验证码，设备显示验证码后，APP发起绑定，然后设备用此接口进行绑定应答。
 * @param binderId 绑定的设备ID
 * @param verificationCode 设备验证码，无账号登陆时候会带上
 * @param status 应答状态， 0x01 接受  0x02 拒绝  0x03 忽略
 * @return
 */
extern PBEncResult
    weilapb_buildAnswerBindExtensionReq(PB_UINT32 binderId, PB_CHAR* pVerificationCode, PB_UINT32 status);

/**
 * 设置设备属性
 * @param name 属性名称
 * @param content 属性
 * @return
 */
extern PBEncResult weilapb_buildSetExtensionConfigReq(PB_CHAR* name, PB_CHAR* content);

/**
 * 发送文字即时信息
 * @param sessionId 会话id，如果是群，则是群id， 如果是个人，则是对方的userId，如果是服务，则是 （服务ID|用户ID)的组合
 * @param sessionType 会话类型，标明是群会话还是个人会话，还是服务会话
 * @param senderId 发送者用户id
 * @param pText 文字，最多1000字，超过返回错误。
 * @return
 */
extern PBEncResult
    weilapb_buildSendText(PB_UINT64 sessionId, PB_UINT16 sessionType, PB_UINT32 senderId, PB_CHAR* pText);

/**
 * 发送图片。图片需要实现上传到服务器，取到服务器的URL后，再调用此函数进行编码
 * @param sessionId
 * @param sessionType
 * @param senderId
 * @param pImageUrl 图片在服务器的URL
 * @return
 */
extern PBEncResult
    weilapb_buildSendImage(PB_UINT64 sessionId, PB_UINT16 sessionType, PB_UINT32 senderId, PB_CHAR* pImageUrl);

/**
 * 发送文件，分为普通文件或视频文件，两者均需要先上传服务器，取到服务器的URL后方可调用此函数进行消息编码
 * @param sessionId
 * @param sessionType
 * @param senderId
 * @param pFileInfo 文件信息，包含文件大小，名字，服务器的URL
 * @param isVideo 是否是视频文件
 * @return
 */
extern PBEncResult weilapb_buildSendFile(PB_UINT64   sessionId,
                                         PB_UINT16   sessionType,
                                         PB_UINT32   senderId,
                                         PBFileInfo* pFileInfo,
                                         PB_BOOL     isVideo);

/**
 * 发送位置分享消息
 * @param sessionId
 * @param sessionType
 * @param senderId
 * @param pSharedInfo 位置分享信息，包含地图类型，街道名字，街道地址，地图的URL
 * @return
 */
extern PBEncResult weilapb_buildSendLocationShare(PB_UINT64             sessionId,
                                                  PB_UINT16             sessionType,
                                                  PB_UINT32             senderId,
                                                  PBLocationInfoShared* pSharedInfo);

/**
 *
 * @param sessionId
 * @param sessionType
 * @param senderId
 */
extern void weilapb_startPttAudio(PB_UINT64 sessionId, PB_UINT16 sessionType, PB_UINT32 senderId);

/**
 * 发送ptt语音帧，每帧都必须是20ms的opus语音，一次发包建议走25帧，但这个不是一定的。尾帧可能就比25少。
 * @param frameType
 * @param PBLinkList 帧链表，每一个项都是一个opus的20ms的数据和大小
 * @param listCount 帧数
 * @return
 */
extern PBEncResult weilapb_buildSendPttFrames(PB_UINT32 frameType, PB_UINT32 sourceType, PBLinkList* pFrameList);

/**
 * 发送ptt语音帧，每帧都必须是20ms的opus语音，一次发包建议走25帧，但这个不是一定的。尾帧可能就比25少。
 * @param burstData 语音数据
 * @return
 */
extern PBEncResult weilapb_buildSendBurstData(PBBurstData* burstData);

/**
 * 获取会话列表信息
 * @param latestUpdateTimeStamp 上一次更新的时间戳（UTC 秒），可以填0
 * @return
 */
extern PBEncResult weilapb_buildGetSessionReq(PB_UINT64 latestUpdateTimeStamp);

/**
 * 删除指定会话列表
 * @param sessionId
 * @param sessionType
 * @return
 */
extern PBEncResult weilapb_buildRemoveSessionReq(PB_UINT64 sessionId, PB_UINT16 sessionType);

/**
 * 附着会话，对于特定嵌入式的设备，所有的群会话必须调用附着动作后，才能接收来自服务器的消息。
 * @param pSessionInfoList
 * @param count
 * @return
 */
extern PBEncResult weilapb_buildEmbeddedAttachSession(PBSessionInfo* pSessionInfoList, PB_UINT32 count);

/**
 * 发起抢麦
 * @param sessionId
 * @param sessionType
 * @param burstType
 * @return
 */
extern PBEncResult weilapb_buildBurstControlReq(PB_UINT64 sessionId, PB_UINT16 sessionType, PB_UINT16 burstType);

/**
 * 对某个会话设置已读消息的id，这个是同步本地已读和服务器的已读id
 * @param sessionId
 * @param sessionType
 * @param msgId
 * @return
 */
extern PBEncResult weilapb_buildSetReadMsgReq(PB_UINT64 sessionId, PB_UINT16 sessionType, PB_UINT32 msgId);

/**
 * 获取指定消息id之间的消息列表。
 * @param sessionId
 * @param sessionType
 * @param fromMsgId 开始消息id
 * @param toMsgId 结束消息id
 * @return
 */
extern PBEncResult
    weilapb_buildGetUnreadMsgReq(PB_UINT64 sessionId, PB_UINT16 sessionType, PB_UINT32 fromMsgId, PB_UINT32 toMsgId);

/**
 * 获取指定msg id后的指定条数的消息列表
 * @param sessionId
 * @param sessionType
 * @param msgId 消息id
 * @param count 条数
 * @return
 */
extern PBEncResult weilapb_buildGetMsgReq(PB_UINT64 sessionId, PB_UINT16 sessionType, PB_UINT32 msgId, PB_UINT32 count);

/**
 * 获取登录用户所在群的群id和群版本信息
 * @return
 */
extern PBEncResult weilapb_buildGetGroupVersionReq(void);

/**
 * 获取指定群id的群属性
 * @param groupId 群id，可以从获取群版本的接口返回获得
 * @return
 */
extern PBEncResult weilapb_buildGetGroupAttributeReq(PB_UINT64 groupId);

/**
 * 创建新的群，此群可以是临时群或正式群，可以设定是否公开，
 * @param pName
 * @param groupType 群类型： 0x01 正式群， 0x02 临时群
 * @param publicType 公开类型： 1 公开， 2 不公开
 * @param pAvatar 头像网址
 * @param pMemberIdList 成员id列表
 * @param memberCount 成员数
 * @return
 */
extern PBEncResult weilapb_buildCreateGroupReq(PB_CHAR*   pName,
                                               PB_UINT16  groupType,
                                               PB_UINT16  publicType,
                                               PB_CHAR*   pAvatar,
                                               PB_UINT32* pMemberIdList,
                                               PB_UINT32  memberCount);

/**
 * 修改群属性，传入的参数是群的属性
 * @param groupId 群id
 * @param pChangeGroupAttr 需要修改的部分
 * @return
 */
extern PBEncResult weilapb_buildChangeGroupAttrReq(PB_UINT32 groupId, PBChangeGroupAttr* pChangeGroupAttr);

/**
 * 获取群相关的信息
 * @param groupId 群id
 * @param memberVersion 群成员版本信息，可以从GetGroupVersion的返回结果获取
 * @return
 */
extern PBEncResult weilapb_buildGetGroupInfoReq(PB_UINT32 groupId, PB_UINT32 memberVersion);

/**
 * 获取登录用户所在群的群id和群版本信息
 * @return
 */
extern PBEncResult weilapb_buildEmbeddedGetGroupVersionReq(PB_UINT32 limit);

/**
 * 获取群信息，只给特定的嵌入式使用
 * @param pGroupIdList 群Id数组
 * @param count
 * @return
 */
extern PBEncResult weilapb_buildEmbeddedGetGroupInfoReq(PB_UINT64* pGroupIdList, PB_UINT32 count);

/**
 * 获取群在线成员id列表
 * @param groupId 群id
 * @return
 */
extern PBEncResult weilapb_buildGetOnlineMemeberReq(PB_UINT32 groupId);

/**
 * 修改群成员的属性，包括是否禁言，是否打开共享，是否打开文字转语音，是否屏蔽消息等
 * @param groupId 群id
 * @param memberId 成员id
 * @param pbChangeMemberInfo
 * @return
 */
extern PBEncResult
    weilapb_buildChangeMemberInfoReq(PB_UINT64 groupId, PB_UINT32 memberId, PBChangeMemberInfo* pbChangeMemberInfo);

/**
 * 获取群成员信息
 * @param groupId
 * @param pUserIdList 群成员id列表
 * @param listCount 群成员列表数目
 * @param memberType 成员类型 0x01 普通， 0x02 管理员
 * @return
 */
extern PBEncResult weilapb_buildGetGroupUserInfoReq(PB_UINT64  groupId,
                                                    PB_UINT32* pUserIdList,
                                                    PB_UINT32  listCount,
                                                    PB_UINT16  memberType);

/**
 * 删除部分群成员
 * @param groupId
 * @param pUserIdList 群成员列表
 * @param listCount 列表数目
 * @return
 */
extern PBEncResult weilapb_buildDelGroupMemberReq(PB_UINT64 groupId, PB_UINT32* pUserIdList, PB_UINT32 listCount);

/**
 * 删除指定群id的群
 * @param groupId 群id
 * @return
 */
extern PBEncResult weilapb_buildDelGroupReq(PB_UINT64 groupId);

/**
 * 获取群申请信息
 * @param latestUpdateTimestamp 最近更新过得时间，UTC时间戳，秒
 * @return
 */
extern PBEncResult weilapb_buildGetGroupInvitationInfoReq(PB_UINT32 latestUpdateTimestamp);

/**
 * 邀请指定用户id的进群
 * @param groupId
 * @param pUserIdList 指定的用户id列表
 * @param listCount 列表数目
 * @return
 */
extern PBEncResult weilapb_buildGroupInviteReq(PB_UINT64 groupId, PB_UINT32* pUserIdList, PB_UINT32 listCount);

/**
 * 应答群邀请
 * @param groupId
 * @param invitorId
 * @param answerStatus 0 未处理， 1 接受， 2 拒绝， 3 忽略
 * @return
 */
extern PBEncResult weilapb_buildAnswerGroupInviteReq(PB_UINT64 groupId, PB_UINT32 invitorId, PB_UINT16 answerStatus);

/**
 * 获取指定群id列表的入群信息
 * @param pGroupIdList 群id列表
 * @param listCount 列表大小
 * @param latestUpdatedTimestamp
 * @return
 */
extern PBEncResult
    weilapb_buildGetGroupJoinInfoReq(PB_UINT64* pGroupIdList, PB_UINT32 listCount, PB_UINT32 latestUpdatedTimestamp);

/**
 * 加入群请求
 * @param groupId
 * @param pDetail 加入群的原因，可以为PB_NULL
 * @param pPassword 入群密码，如果群是需要认证的，则需要输入密码，否则可以填PB_NULL
 * @return
 */
extern PBEncResult weilapb_buildJoinGroupReq(PB_UINT64 groupId, PB_CHAR* pDetail, PB_CHAR* pPassword);

/**
 * 应答入群请求
 * @param groupId
 * @param joinerId 入群请求者id
 * @param answerStatus 应答状态 0 未处理， 1 接受， 2 拒绝， 3 忽略
 * @return
 */
extern PBEncResult weilapb_buildAnswerGroupJoinReq(PB_UINT64 groupId, PB_UINT32 joinerId, PB_UINT16 answerStatus);

/**
 * 开启或关闭群广播功能
 * @param groupId
 * @param status 0 关闭， 1 开启
 * @return
 */
extern PBEncResult weilapb_buildGroupBroadcastReq(PB_UINT64 groupId, PB_UINT32 status);

/**
 * 获取群的黑名单
 * @param groupId
 * @param pageIndex 页码索引
 * @param pageSize 一页数量
 * @return
 */
extern PBEncResult weilapb_buildGetGroupBlacklistReq(PB_UINT64 groupId, PB_UINT32 pageIndex, PB_UINT32 pageSize);

/**
 *  添加或删除群黑名单用户
 * @param groupId
 * @param pUserIdList
 * @param listCount
 * @param status 0 添加 1 删除
 * @return
 */
extern PBEncResult weilapb_buildChangeGroupBlacklistReq(PB_UINT64  groupId,
                                                        PB_UINT32* pUserIdList,
                                                        PB_UINT32  listCount,
                                                        PB_UINT32  status);

/**
 * 修改登录用户的属性
 * @param pChangeUserInfo 需要修改的参数
 * @return
 */
extern PBEncResult weilapb_buildChangeUserInfoReq(PBChangeUserInfo* pChangeUserInfo);

/**
 * 获取指定类型的配置,服务器返回的是json响应数据
 * @return
 */
extern PBEncResult weilapb_buildGetConfigReq(void);

/**
 * 设置对应的配置
 * @param userId
 * @param pKeyName 配置名
 * @param Content 配置内容
 * @return
 */
extern PBEncResult weilapb_buildSetConfigReq(PB_UINT32 userId, PB_CHAR* pKeyName, PB_CHAR* pContent);

/**
 * 上报位置，可以附带上额外的业务
 * @param pSessionInfoList  会话列表信息，上报可以上报一系列的会话id
 * @param count 会话列表的数量
 * @param pLocationInfo 位置信息
 * @param pExtraInfo 额外的业务
 * @return
 */
extern PBEncResult weilapb_buildReportLocationReq(PBSessionInfo*       pSessionInfoList,
                                                  PB_UINT32            count,
                                                  PBLocationInfo*      pLocationInfo,
                                                  PBLocationExtraInfo* pExtraInfo);

/**
 * 获取对应会话的位置信息
 * @param sessionId 如果是个人，则是userId，是群，则是群ID，如果是服务，则是（服务ID|用户ID）
 * @param sessionType
 * @return
 */
extern PBEncResult weilapb_buildGetLocationReq(PB_UINT64 sessionId, PB_UINT16 sessionType);

/**
 * 控制位置上报
 * @param sessionId
 * @param sessionType
 * @param status 状态 0 关闭， 1 开启
 * @param frequency 上报频率
 * @param duration 持续时间
 * @return
 */
extern PBEncResult weilapb_buildLocationControlReq(PB_UINT64 sessionId,
                                                   PB_UINT16 sessionType,
                                                   PB_BOOL   status,
                                                   PB_UINT32 frequency,
                                                   PB_UINT32 duration);

/**
 * 上报轨迹位置
 * @param pLocationInfo 位置信息
 * @return
 */
extern PBEncResult weilapb_buildReportTrackLocationReq(PBLocationInfo* pLocationInfo);

/**
 * 上报服务位置
 * @param pLocationInfo 位置信息
 * @param interval 间隔
 * @param serviceId 服务号Id 0 无效
 * @return
 */
extern PBEncResult
    weilapb_buildReportBusinessLocationReq(PBLocationInfo* pLocationInfo, PB_UINT32 interval, PB_UINT32 serviceId);

/**
 * 更新好友概况信息
 * @param latestTimestamp 最近更新时间
 * @return
 */
extern PBEncResult weilapb_buildGetFriendInfoReq(PB_UINT64 latestTimestamp);

/**
 * 获取好友用户信息
 * @param pUserIdList 好友id的列表
 * @param listCount
 * @return
 */
extern PBEncResult weilapb_buildGetFriendUserInfoReq(PB_UINT32* pUserIdList, PB_UINT32 listCount);

/**
 * 获取好友申请信息
 * @param latestTimestamp
 * @return
 */
extern PBEncResult weilapb_buildGetFriendInviteInfoReq(PB_UINT64 latestTimestamp);

/**
 * 对特定的用户id发送邀请请求
 * @param inviteeId 发送对象id
 * @param pDetail 请求原因
 * @param pRemark 标注
 * @return
 */
extern PBEncResult weilapb_buildFriendInviteReq(PB_UINT32 inviteeId, PB_CHAR* pDetail, PB_CHAR* pRemark);

/**
 * 应答好友申请
 * @param invitorId 请求发送者id
 * @param answerStatus 应答状态 1 接受， 2 拒绝， 3忽略
 * @param pRemark
 * @return
 */
extern PBEncResult weilapb_buildAnswerFriendInviteReq(PB_UINT32 invitorId, PB_UINT32 answerStatus, PB_CHAR* pRemark);

/**
 * 删除指定用户id的好友
 * @param userId
 * @return
 */
extern PBEncResult weilapb_buildDeleteFriendReq(PB_UINT32 userId);

/**
 * 修改指定好友的属性
 * @param friendId 好友id
 * @param pChangeFriendInfo
 * @return
 */
extern PBEncResult weilapb_buildChangeFriendInfoReq(PB_UINT32 friendId, PBChangeFriendInfo* pChangeFriendInfo);

/**
 * 获取好友黑名单
 * @param pageIndex
 * @param pageSize
 * @return
 */
extern PBEncResult weilapb_buildGetFriendBlacklistReq(PB_UINT32 pageIndex, PB_UINT32 pageSize);

/**
 * 修改好友的黑名单
 * @param pUserIdList 修改的用户id
 * @param listCount
 * @param status
 * @return
 */
extern PBEncResult weilapb_buildChangeFriendBlacklistReq(PB_UINT32* pUserIdList, PB_UINT32 listCount, PB_UINT32 status);

/**
 * 获取在线好友
 * @return
 */
extern PBEncResult weilapb_buildGetOnlineFriendReq(void);

/**
 * 发起VOIP邀请
 * @param userId 被叫
 * @return
 */
extern PBEncResult weilapb_buildVoipInviteReq(PB_CHAR* callId, PB_UINT32 userId);

/**
 * 接听VOIP
 * @param userId 主叫
 * @return
 */
extern PBEncResult weilapb_buildVoipAcceptReq(PB_CHAR* callId, PB_UINT32 userId);

/**
 * 挂断VOIP
 * @param userId 远端用户
 * @return
 */
extern PBEncResult weilapb_buildVoipHangupReq(PB_CHAR* callId, PB_UINT32 userId);

/**
 * 依据当前时间信息来获取好友信息。此版本只适合特定的嵌入式版本，获取的信息有裁剪
 * @param latestUpdated
 * @param pUserIdList 用户id
 * @param listCount
 * @param limit
 * @return
 */
extern PBEncResult weilapb_buildEmbeddedGetFriendInfo(PB_UINT64  latestUpdated,
                                                      PB_UINT32* pUserIdList,
                                                      PB_UINT32  listCount,
                                                      PB_UINT32  limit);

/**
 *
 * @param pPbEncResult
 */
extern void weilapb_releasePBEncResult(PBEncResult* pPbEncResult);

/**
 *
 * @param pPbWeilaMsg
 */
extern void weilapb_releasePBWeilaMsg(PBWeilaMsg* pPbWeilaMsg);
#endif  // WEILACSDK_WEILAPB_H
